package com.javacv.plus.core.event;

import lombok.Data;
import lombok.EqualsAndHashCode;

import java.time.LocalDateTime;

/**
 * 处理器事件基类
 * 所有处理器事件都应该继承此类
 */
@Data
public abstract class ProcessorEvent {
    
    private final String eventId;
    private final LocalDateTime timestamp;
    private final String source;
    
    protected ProcessorEvent(String source) {
        this.eventId = generateEventId();
        this.timestamp = LocalDateTime.now();
        this.source = source;
    }
    
    private String generateEventId() {
        return System.currentTimeMillis() + "-" + Thread.currentThread().getId();
    }
    
    /**
     * 处理开始事件
     */
    @Data
    @EqualsAndHashCode(callSuper = true)
    public static class ProcessingStartedEvent extends ProcessorEvent {
        private final String processorType;
        private final String inputPath;
        
        public ProcessingStartedEvent(String source, String processorType, String inputPath) {
            super(source);
            this.processorType = processorType;
            this.inputPath = inputPath;
        }
    }
    
    /**
     * 处理完成事件
     */
    @Data
    @EqualsAndHashCode(callSuper = true)
    public static class ProcessingCompletedEvent extends ProcessorEvent {
        private final String processorType;
        private final String outputPath;
        private final long duration;
        private final boolean success;
        
        public ProcessingCompletedEvent(String source, String processorType, 
                                      String outputPath, long duration, boolean success) {
            super(source);
            this.processorType = processorType;
            this.outputPath = outputPath;
            this.duration = duration;
            this.success = success;
        }
    }
    
    /**
     * 步骤开始事件
     */
    @Data
    @EqualsAndHashCode(callSuper = true)
    public static class StepStartedEvent extends ProcessorEvent {
        private final String stepName;
        private final int stepIndex;
        private final Object stepConfig;
        
        public StepStartedEvent(String source, String stepName, int stepIndex, Object stepConfig) {
            super(source);
            this.stepName = stepName;
            this.stepIndex = stepIndex;
            this.stepConfig = stepConfig;
        }
    }
    
    /**
     * 步骤完成事件
     */
    @Data
    @EqualsAndHashCode(callSuper = true)
    public static class StepCompletedEvent extends ProcessorEvent {
        private final String stepName;
        private final int stepIndex;
        private final long duration;
        private final boolean success;
        private final String errorMessage;
        
        public StepCompletedEvent(String source, String stepName, int stepIndex, 
                                long duration, boolean success, String errorMessage) {
            super(source);
            this.stepName = stepName;
            this.stepIndex = stepIndex;
            this.duration = duration;
            this.success = success;
            this.errorMessage = errorMessage;
        }
    }
    
    /**
     * 错误事件
     */
    @Data
    @EqualsAndHashCode(callSuper = true)
    public static class ErrorEvent extends ProcessorEvent {
        private final String errorType;
        private final String errorMessage;
        private final Throwable exception;
        private final Object context;
        
        public ErrorEvent(String source, String errorType, String errorMessage, 
                        Throwable exception, Object context) {
            super(source);
            this.errorType = errorType;
            this.errorMessage = errorMessage;
            this.exception = exception;
            this.context = context;
        }
    }
    
    /**
     * 缓存事件
     */
    @Data
    @EqualsAndHashCode(callSuper = true)
    public static class CacheEvent extends ProcessorEvent {
        private final String operation; // HIT, MISS, PUT, EVICT
        private final String cacheKey;
        private final Object value;
        
        public CacheEvent(String source, String operation, String cacheKey, Object value) {
            super(source);
            this.operation = operation;
            this.cacheKey = cacheKey;
            this.value = value;
        }
    }
    
    /**
     * 资源事件
     */
    @Data
    @EqualsAndHashCode(callSuper = true)
    public static class ResourceEvent extends ProcessorEvent {
        private final String resourceType;
        private final String resourceId;
        private final String operation; // ACQUIRE, RELEASE, CLEANUP
        private final long memoryUsage;
        
        public ResourceEvent(String source, String resourceType, String resourceId, 
                           String operation, long memoryUsage) {
            super(source);
            this.resourceType = resourceType;
            this.resourceId = resourceId;
            this.operation = operation;
            this.memoryUsage = memoryUsage;
        }
    }
} 